home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Talking Clock Pro™ 2.0.1 / Talking Clock Pro Source / Controller / Source / clwinrec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-24  |  11.0 KB  |  501 lines  |  [TEXT/CWIE]

  1. /*
  2.  * clwinrec.c
  3.  */
  4.  
  5. #include <AERegistry.h>
  6. #include <AEObjects.h>
  7. #include <QDOffscreen.h>
  8.  
  9. #include <Icons.h>    //    #include <PlotIconSuite.h>
  10. #include "TalkConstants.h"
  11.  
  12. #include "apprec.h"
  13. #include "clwinrec.h"
  14. #include "x.h"
  15. #include "menu.h"
  16. #include "window.h"
  17. #include "util.h"
  18. #include "str.h"
  19.  
  20. #define MAX_SIZE 500
  21. #define MIN_SIZE 5
  22.  
  23.  
  24. DefWindowRec clwinRec = {
  25.  
  26.     129 , NULL ,
  27.  
  28.     ClwinCr ,
  29.     ClwinDe ,
  30.     ClwinUp ,
  31.     ClwinMD ,
  32.     ClwinMU ,
  33.     ClwinKD ,
  34.     ClwinAK ,
  35.     ClwinAc ,
  36.     NULL ,
  37.     ClwinId ,
  38.     ClwinPr ,
  39.     ClwinCo ,
  40.     ClwinAE
  41.  
  42. } ;
  43.  
  44.  
  45. typedef struct ClWinData {
  46.     Str32        fontName ;
  47.     short        fontSize ;
  48.     short        baseLine ;
  49.     short        winHeight ;
  50.     short        winWid ;
  51.     short        winX ;
  52.     short        winY ;
  53.     short        lastMin ;
  54.     short        lastSec ;
  55.     Boolean        showSecs ;
  56.     Boolean        smoothUpdates ;
  57.     Boolean        antiAlias ;
  58. } ClWinData , * ClWinPtr ;
  59.  
  60.  
  61. static short
  62. MaxDigWid ( void ) {
  63.  
  64. short wid = 0 ;
  65. char dig ;
  66. short w ;
  67.  
  68.     for ( dig = '0' ; dig <= '9' ; dig ++ ) {
  69.         w = CharWidth ( dig ) ;
  70.         if ( w > wid ) {
  71.             wid = w ;
  72.         }
  73.     }
  74.     return wid ;
  75. }
  76.  
  77.  
  78. static void
  79. ClWindowCalc ( ClWinPtr ptr , WindowPtr wp ) {
  80.  
  81. FontInfo fi ;
  82. short num ;
  83. Point p = { 0 , 0 } ;
  84.  
  85.     SetPort ( wp ) ;
  86.     GetFNum ( ptr -> fontName , & num ) ;
  87.     TextFont ( num ) ;
  88.     TextSize ( ptr -> fontSize ) ;
  89.     GetFontInfo ( & fi ) ;
  90.     ptr -> baseLine = fi . ascent + fi . leading ;
  91.     ptr -> winHeight = ptr -> baseLine + fi . descent + fi . leading ;
  92.     ptr -> winWid = MaxDigWid ( ) * ( ptr -> showSecs ? 9 : 7 ) ;
  93.     LocalToGlobal ( & p ) ;
  94.     ptr -> winX = p . h ;
  95.     ptr -> winY = p . v ;
  96.     if ( ptr -> smoothUpdates ) {
  97.         if ( ! OffscreenAvailable ( ) ) {
  98.             ptr -> smoothUpdates = 0 ;
  99.         }
  100.     }
  101.     SizeWindow ( wp , ptr -> winWid , ptr -> winHeight , 1 ) ;
  102.     InvalRect ( & ( wp -> portRect ) ) ;
  103. }
  104.  
  105.  
  106. /*    A window is being created or opened. Allocate data and        */
  107. /*    select the window                                    */
  108. OSErr
  109. ClwinCr ( WindowPtr wp , Handle * data , FSSpec * file ) {
  110.  
  111. ClWinPtr ptr ;
  112.  
  113.     ClWinAdd ( wp , app . data ) ;
  114.     * data = NewHandleClear ( sizeof ( ClWinData ) ) ;
  115.     HLockHi ( * data ) ;
  116.     ptr = ( ClWinPtr ) * * data ;
  117.     GetFontName ( GetAppFont ( ) , ptr -> fontName ) ;
  118.     ptr -> showSecs = 0 ;
  119.     ptr -> fontSize = GetDefFontSize ( ) ;
  120.     ClWindowCalc ( ptr , wp ) ;
  121.     SelectWindow ( wp ) ;
  122.     ShowWindow ( wp ) ;
  123.     return noErr ;
  124. }
  125.  
  126.  
  127. /*    Window is being destroyed. Put up a warning dialog, and        */
  128. /*    return errCancel if the user cancels closing - else call    */
  129. /*    DisposeWindow here                                            */
  130. OSErr
  131. ClwinDe ( WindowPtr wp , Handle data ) {
  132.  
  133.     ClWinRemove ( wp , app . data ) ;
  134.     DisposeHandle ( data ) ;
  135.     DisposeWindow ( wp ) ;
  136.     return noErr ;
  137. }
  138.  
  139.  
  140. /*    Update the window - BeginUpdate is already called            */
  141. OSErr
  142. ClwinUp ( WindowPtr wp , Handle data , EventRecord * event ) {
  143.  
  144. Str63 time ;
  145. unsigned long now ;
  146. ClWinPtr ptr = ( ClWinPtr ) * data ;
  147. short pos ;
  148. short num ;
  149. Boolean doSmooth = ptr -> smoothUpdates ;
  150. GWorldPtr lptr = NULL , sptr = NULL ;
  151. PixMapHandle lpix = NULL , spix = NULL ;
  152. Rect r , r2 ;
  153. short err ;
  154. Point p = { 0 , 0 } ;
  155. short mul = 1 ;
  156.  
  157.     GetDateTime ( & now ) ;
  158.     IUTimeString ( now , ptr -> showSecs , time ) ;
  159.     GetFNum ( ptr -> fontName , & num ) ;
  160.     TextFont ( num ) ;
  161.     TextSize ( ptr -> fontSize ) ;
  162.     pos = ( ptr -> winWid - StringWidth ( time ) ) / 2 ;
  163.  
  164.     if ( doSmooth ) {
  165.         r = wp -> portRect ;
  166.         LocalToGlobal ( & p ) ;
  167.         OffsetRect ( & r , p . h , p . v ) ;
  168.         err = NewGWorld ( & sptr , 0 , & r , NULL , NULL , useTempMem ) ;
  169.         OffsetRect ( & r , - p . h , - p . v ) ;
  170.     } else {
  171.         err = 1 ;
  172.     }
  173.     if ( ptr -> antiAlias && ! err ) {
  174.         r2 = wp -> portRect ;
  175.         if ( ptr -> fontSize > 24 ) {
  176.             r2 . right <<= 1 ;
  177.             r2 . bottom <<= 1 ;
  178.             mul = 2 ;
  179.         } else {
  180.             r2 . right <<= 2 ;
  181.             r2 . bottom <<= 2 ;
  182.             mul = 4 ;
  183.         }
  184.         err = NewGWorld ( & lptr , 0 , & r2 , NULL , NULL , useTempMem ) ;
  185.     }
  186.     if ( sptr && lptr && ! err ) {
  187.     GWorldPtr oldWorld ;
  188.     GDHandle oldGD ;
  189.         LockPixels ( GetGWorldPixMap ( lptr ) ) ;
  190.         GetGWorld ( & oldWorld , & oldGD ) ;
  191.         SetGWorld ( lptr , NULL ) ;
  192.         EraseRect ( & r2 ) ;
  193.         TextFont ( num ) ;
  194.         TextSize ( ptr -> fontSize * mul ) ;
  195.         MoveTo ( pos * mul , ptr -> baseLine * mul ) ;
  196.         DrawString ( time ) ;
  197.         LockPixels ( GetGWorldPixMap ( sptr ) ) ;
  198.         SetGWorld ( sptr , NULL ) ;
  199.         CopyBits ( ( BitMapPtr ) & ( ( ( GrafPtr ) lptr ) -> portBits ) ,
  200.             ( BitMapPtr ) & ( ( ( GrafPtr ) sptr ) -> portBits ) , & r2 , & r ,
  201.             ditherCopy , NULL ) ;
  202.         UnlockPixels ( GetGWorldPixMap ( lptr ) ) ;
  203.         SetGWorld ( oldWorld , oldGD ) ;
  204.     } else if ( sptr && ! err ) {
  205.     GWorldPtr oldWorld ;
  206.     GDHandle oldGD ;
  207.         LockPixels ( GetGWorldPixMap ( sptr ) ) ;
  208.         GetGWorld ( & oldWorld , & oldGD ) ;
  209.         SetGWorld ( sptr , NULL ) ;
  210.         EraseRect ( & r ) ;
  211.         TextFont ( num ) ;
  212.         TextSize ( ptr -> fontSize ) ;
  213.         MoveTo ( pos + r . left , ptr -> baseLine + r . top ) ;
  214.         DrawString ( time ) ;
  215.         SetGWorld ( oldWorld , oldGD ) ;
  216.     } else {
  217.         err = err ? err : 1 ;
  218.     }
  219.     doSmooth = ! err ;
  220.  
  221. /* Don't erase until we know what to do! */
  222.     if ( ! doSmooth ) {
  223.         EraseRect ( & ( wp -> portRect ) ) ;
  224.         MoveTo ( pos , ptr -> baseLine ) ;
  225.         DrawString ( time ) ;
  226.     } else {
  227.         CopyBits ( ( BitMapPtr ) & ( ( ( GrafPtr ) sptr ) -> portBits ) ,
  228.             & ( wp -> portBits ) , & r , & ( wp -> portRect ) , srcCopy , NULL ) ;
  229.     }
  230.     if ( lptr ) {
  231.         DisposeGWorld ( lptr ) ;
  232.     }
  233.     if ( sptr ) {
  234.         DisposeGWorld ( sptr ) ;
  235.     }
  236.  
  237.     return noErr ;
  238. }
  239.  
  240.  
  241. /*    The user clicked in your window. The window port is set and    */
  242. /*    event -> where is translated into local coordinates now        */
  243. OSErr
  244. ClwinMD ( WindowPtr wp , Handle data , EventRecord * event ) {
  245.  
  246. /* The framework has converted the point to local coordinates; convert back */
  247.     LocalToGlobal ( & ( event -> where ) ) ;
  248.     DragWindow ( wp , event -> where , & gDragLimit ) ;
  249. /* Save the new position */
  250.     ClWindowCalc ( ( ClWinPtr ) * data , wp ) ;
  251.     return noErr ;
  252. }
  253.  
  254.  
  255. /*    MouseUp in a window - you probably should do nothing        */
  256. OSErr
  257. ClwinMU ( WindowPtr wp , Handle data , EventRecord * event ) {
  258.  
  259.     return noErr ;
  260. }
  261.  
  262.  
  263. /*    The user typed in the window - command keys are already        */
  264. /*    taken care of and don't come here                            */
  265. OSErr
  266. ClwinKD ( WindowPtr wp , Handle data , EventRecord * event ) {
  267.  
  268.     return noErr ;
  269. }
  270.  
  271.  
  272. /*    You probably just want to call the KeyDown handler here        */
  273. OSErr
  274. ClwinAK ( WindowPtr wp , Handle data , EventRecord * event ) {
  275.  
  276.     return noErr ;
  277. }
  278.  
  279.  
  280. /*    Activate event - highlight/dehighlight controls & caret        */
  281. OSErr
  282. ClwinAc ( WindowPtr wp , Handle data , EventRecord * event ) {
  283.  
  284.     if ( event -> modifiers & activeFlag ) {
  285.         EnableCmd ( FONT_MENU , 0 ) ;
  286.         EnableCmd ( SIZE_MENU , 0 ) ;
  287.         EnableCmd ( CLOCK_MENU , 0 ) ;
  288.     } else {
  289.         DisableCmd ( FONT_MENU , 0 ) ;
  290.         DisableCmd ( SIZE_MENU , 0 ) ;
  291.         DisableCmd ( CLOCK_MENU , 0 ) ;
  292.     }
  293.     return noErr ;
  294. }
  295.  
  296.  
  297. /*    You should probably build a suitable activate event and        */
  298. /*    send to the activate handling for MultiFinder switches        */
  299. /*    In this application, we set this record field to NULL to        */
  300. /*    pass the event to the application instead.                */
  301. OSErr
  302. ClwinSw ( WindowPtr wp , Handle data , EventRecord * event ) {
  303.  
  304.     return noErr ;
  305. }
  306.  
  307.  
  308. /*    Idle time - set the sleep parameter if it's too large for    */
  309. /*    your needs. GetCaretTime() is a good value for text editors    */
  310. OSErr
  311. ClwinId ( WindowPtr wp , Handle data , long * sleep ) {
  312.  
  313.     return AppId ( wp , app . data , sleep ) ;
  314. }
  315.  
  316.  
  317. /*    This is called when menus need to be updated.                */
  318. OSErr
  319. ClwinPr ( WindowPtr wp , Handle data ) {
  320.  
  321. Str15 num ;
  322. ClWinPtr ptr = ( ClWinPtr ) * data ;
  323. short fNum ;
  324.  
  325.     FailErr ( AppPr ( wp , app . data ) ) ;
  326.     EnableCmd ( FILE_MENU , CLOSE_ITEM ) ;
  327.     SetPort ( wp ) ;
  328.     GetFNum ( ptr -> fontName , & fNum ) ;
  329.     EnableMenu ( FONT_MENU ) ;
  330.     EnableMenu ( SIZE_MENU ) ;
  331.     SizeMenuOutlines ( fNum ) ;
  332.     DisableCmd ( SIZE_MENU , SIZE_DELIMITER ) ;
  333.     CheckStr ( FONT_MENU , ptr -> fontName , 1 ) ;
  334.     NumToString ( ptr -> fontSize , num ) ;
  335.     CheckStr ( SIZE_MENU , num , 1 ) ;
  336.     EnableCmd ( CLOCK_MENU , SECONDS_ITEM ) ;
  337.     CheckCmd ( CLOCK_MENU , SECONDS_ITEM , ptr -> showSecs ) ;
  338.     if ( OffscreenAvailable ( ) ) {
  339.         EnableCmd ( CLOCK_MENU , SMOOTH_ITEM ) ;
  340.         CheckCmd ( CLOCK_MENU , SMOOTH_ITEM , ptr -> smoothUpdates ) ;
  341.         if ( ptr -> smoothUpdates ) {
  342.             EnableCmd ( CLOCK_MENU , ANTI_ALIAS_ITEM ) ;
  343.             CheckCmd ( CLOCK_MENU , ANTI_ALIAS_ITEM , ptr -> antiAlias ) ;
  344.         }
  345.     }
  346.     return noErr ;
  347. }
  348.  
  349.  
  350. /*    A menu selection was made - take appropriate action            */
  351. OSErr
  352. ClwinCo ( WindowPtr wp , Handle data , short menu , short item ,
  353.     unsigned char * itemStr ) {
  354.  
  355. ClWinPtr ptr = ( ClWinPtr ) * data ;
  356. long size ;
  357.  
  358.     if ( menu == FILE_MENU && item == CLOSE_ITEM ) {
  359.         DestroyWindow ( wp ) ;
  360.     } else if ( menu == FONT_MENU ) {
  361.         CopyPString ( itemStr , ptr -> fontName ) ;
  362.         ClWindowCalc ( ptr , wp ) ;
  363.     } else if ( menu == SIZE_MENU ) {
  364.         switch ( item ) {
  365.         case SMALLER_ITEM :
  366.             if ( ptr -> fontSize > MIN_SIZE ) {
  367.                 if ( KeyIsDown ( 0x3a ) ) {
  368.                     ptr -> fontSize >>= 1 ;
  369.                     if ( ptr -> fontSize < MIN_SIZE ) {
  370.                         ptr -> fontSize = MIN_SIZE ;
  371.                     }
  372.                 } else {
  373.                     ptr -> fontSize -- ;
  374.                 }
  375.             }
  376.             break ;
  377.         case LARGER_ITEM :
  378.             if ( ptr -> fontSize < MAX_SIZE ) {
  379.                 if ( KeyIsDown ( 0x3a ) ) {
  380.                     ptr -> fontSize <<= 1 ;
  381.                     if ( ptr -> fontSize > MAX_SIZE ) {
  382.                         ptr -> fontSize = MAX_SIZE ;
  383.                     }
  384.                 } else {
  385.                     ptr -> fontSize ++ ;
  386.                 }
  387.             }
  388.             break ;
  389.         default :
  390.             StringToNum ( itemStr , & size ) ;
  391.             ptr -> fontSize = size ;
  392.             break ;
  393.         }
  394.         ClWindowCalc ( ptr , wp ) ;
  395.     } else if ( menu == CLOCK_MENU ) {
  396.         switch ( item ) {
  397.         case SECONDS_ITEM :
  398.             ptr -> showSecs = ! ptr -> showSecs ;
  399.             break ;
  400.         case SMOOTH_ITEM :
  401.             ptr -> smoothUpdates = ! ptr -> smoothUpdates ;
  402.             break ;
  403.         case ANTI_ALIAS_ITEM :
  404.             ptr -> antiAlias = ! ptr -> antiAlias ;
  405.             break ;
  406.         }
  407.         ClWindowCalc ( ptr , wp ) ;
  408.     } else {
  409.         FailErr ( AppCo ( wp , app . data , menu , item , itemStr ) ) ;
  410.     }
  411.  
  412.     return noErr ;
  413. }
  414.  
  415.  
  416. /*    An AppleEvent was received with this window in front        */
  417. OSErr
  418. ClwinAE ( WindowPtr wp , Handle data , AppleEvent * event ,
  419.     AppleEvent * reply ) {
  420.  
  421.     return noErr ;
  422. }
  423.  
  424.  
  425. void
  426. ClWinWrite ( short refNum , WindowPtr wp ) {
  427.  
  428. DefWindowRec * dr ;
  429. long size ;
  430. ClWinData data ;
  431.  
  432.     if ( ! wp ) {
  433.         return ;
  434.     }
  435.     dr = RecFromWindow ( wp ) ;
  436.     if ( ! dr ) {
  437.         return ;
  438.     }
  439.     data = * ( ClWinPtr ) * ( dr -> data ) ;
  440.     size = sizeof ( ClWinData ) ;
  441.     FailErr ( FSWrite ( refNum , & size , ( Ptr ) & data ) ) ;
  442. }
  443.  
  444.  
  445. void
  446. ClWinRead ( short refNum , WindowPtr wp ) {
  447.  
  448. DefWindowRec * dr ;
  449. long size ;
  450. ClWinData data ;
  451. Point p ;
  452.  
  453.     size = sizeof ( ClWinData ) ;
  454.     FailErr ( FSRead ( refNum , & size , ( Ptr ) & data ) ) ;
  455.  
  456.     if ( ! wp ) {
  457.         return ;
  458.     }
  459.     dr = RecFromWindow ( wp ) ;
  460.     if ( ! dr ) {
  461.         return ;
  462.     }
  463.     * ( ClWinPtr ) * ( dr -> data ) = data ;
  464.     p . h = data . winX + 10 ;
  465.     p . v = data . winY + 5 ;
  466.     if ( PtInRgn ( p , GetGrayRgn ( ) ) ) {
  467.         MoveWindow ( wp , data . winX , data . winY , 1 ) ;
  468.     }
  469.     ClWindowCalc ( ( ClWinPtr ) * ( dr -> data ) , wp ) ;
  470. }
  471.  
  472.  
  473. void
  474. ClWinRunClock ( WindowPtr wp , long * sleep , short nowMin , short nowSec ) {
  475.  
  476. long canSleep ;
  477. DefWindowRec * dr ;
  478. ClWinPtr ptr ;
  479.  
  480.     if ( ! wp ) {
  481.         return ;
  482.     }
  483.     dr = RecFromWindow ( wp ) ;
  484.     if ( ! dr ) {
  485.         return ;
  486.     }
  487.     ptr = ( ClWinPtr ) * ( dr -> data ) ;
  488.  
  489.     canSleep = ptr -> showSecs ? 10 : 180 ;
  490.     if ( * sleep > canSleep ) {
  491.         * sleep = canSleep ;
  492.     }
  493.     if ( ( nowMin != ptr -> lastMin ) ||
  494.         ( ptr -> showSecs && ( nowSec != ptr -> lastSec ) ) ) {
  495.         SetPort ( wp ) ;
  496.         ptr -> lastMin = nowMin ;
  497.         ptr -> lastSec = nowSec ;
  498.         ClwinUp ( wp , dr -> data , NULL ) ;
  499.     }
  500. }
  501.